const assert = require('assert');
const {ether,constants,expectEvent} = require('@openzeppelin/test-helpers');

//导出 detail()函数
exports.detail =() => {
    it('Token名称:name()',async function(){
        assert.equal(ERC20Param[0], await ERC20Instance.name());
    });
    it('Token缩写:symbol()',async function(){
        assert.equal(ERC20Param[1], await ERC20Instance.symbol());
    });
    it('Token精度:decimals()',async function(){
        assert.equal(ERC20Param[2], (await ERC20Instance.decimals()).toString());
    });
    it('Token总量:totalSupply()',async function(){
        assert.equal(ether(ERC20Param[3]).toString(), (await ERC20Instance.totalSupply()).toString());
    });
}

//测试Token总量
exports.totalSupply =(totalSupply) => {
    it('Token总量:totalSupply()',async function(){
        assert.equal(ether(totalSupply).toString(),(await ERC20Instance.totalSupply()).toString());
    });
}

//测试账户余额
exports.balanceOf =(balance,account,desc) => {
    it(desc + ':balanceOf()',async function(){
        assert.equal(ether(balance).toString(), (await ERC20Instance.balanceOf(account)).toString());
    });
}

//测试封顶额度
exports.cap =(cap,desc) => {
    it(desc + ':cap()',async function(){
        assert.equal(ether(cap).toString(), (await ERC20Instance.cap()).toString());
    });
}

//测试Token发送
exports.transfer =(sender,receiver,amount,desc,reject,msg) => {
    it(desc + ':transfer()', async function(){
        if(reject) {
            await assert.rejects(ERC20Instance.transfer(receiver,ether(amount), {from:sender}), msg);
        } else {
            let receipt = await ERC20Instance.transfer(receiver,ether(amount), {from:sender});
            expectEvent(receipt, 'Transfer', {
                from: sender,
                to: receiver,
                value: ether(amount),
            });
        }
    });
}

//测试批准额度
exports.approve = (sender,receiver,amount,desc,reject,msg) => {
    it(desc + ':approve()', async function(){
        if(reject) {
            await assert.rejects(ERC20Instance.approve(receiver,ether(amount),{from:sender}),msg);
        } else {
            let receipt = await ERC20Instance.approve(receiver, ether(amount), { from: sender });
            expectEvent(receipt, 'Approval', {
                owner: sender,
                spender: receiver,
                value: ether(amount),
            });
        }
    });
}

//测试批准发送
exports.transferFrom =(owner,sender,receiver,amount,desc,reject,msg) => {
    it(desc + ':transferFrom()', async function(){
        if (reject) {
            await assert.rejects(ERC20Instance.transferFrom(owner,receiver,ether(amount),{from:sender}), msg);
        } else {
            let receipt = await ERC20Instance.transferFrom(owner,receiver,ether(amount),{from:sender});
            expectEvent(receipt, 'Transfer', {
                from: owner,
                to: receiver,
                value: ether(amount),
            });
        }
    });
}

//测试批准数额
exports.allowance = (owner,sender,amount,desc) => {
    it(desc + ':allowance()',async function(){
        assert.equal(ether(amount), (await ERC20Instance.allowance(owner,sender)).toString());
    });
}

//测试增加批准数额
exports.increaseAllowance = (sender,receiver,amount,desc,reject,msg) => {
    it(desc + ':increaseAllowance()', async function() {
        if(reject) {
            await assert.rejects(ERC20Instance.increaseAllowance(receiver,ether(amount), {from:sender}),msg);
        } else {
            let receipt = await ERC20Instance.increaseAllowance(receiver,ether(amount),{from:sender});
            expectEvent(receipt,'Approval',{
                owner:sender,
                spender: receiver,
            });
        }
    });
}

//批准减少批准额度
exports.decreaseAllowance = (sender,receiver,amount,desc,reject,msg) => {
    it(desc + ': decreaseAllowance()', async function () {
        if(reject) {
            await assert.rejects(ERC20Instance.decreaseAllowance(receiver, ether(amount), { from: sender }), msg);
        } else {
            let receipt = await ERC20Instance.decreaseAllowance(receiver,ether(amount),{from:sender});
            expectEvent(receipt,'Approval',{
                owner: sender,
                spender:receiver,
            });
        }
    });
}

//测试销毁方法
exports.burn = (sender,amount,desc,reject,msg) => {
    it(desc + ':burn()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.burn(ether(amount),{from:sender}), msg);
        } else {
            let receipt = await ERC20Instance.burn(ether(amount), { from: sender });
            expectEvent(receipt, 'Transfer', {
                from: sender,
                to: constants.ZERO_ADDRESS,
                value: ether(amount),
            });
        }
    });
}

//测试销毁批准方法
exports.burnFrom = (owner,sender,amount,desc,reject,msg) => {
    it(desc + ':burnFrom()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.burnFrom(owner,ether(amount),{from:sender}),msg);
        } else {
            let receipt = await ERC20Instance.burnFrom(owner,ether(amount),{from:sender});
            expectEvent(receipt,'Transfer',{
                from: owner,
                to: constants.ZERO_ADDRESS,
                value: ether(amount),
            });
            expectEvent(receipt,'Approval', {
                owner: owner,
                spender: sender,
            });
        }
    });
}

//测试铸币方法
exports.mint = (owner,beneficiary,amount,desc,reject,msg) => {
    it(desc + ':mint()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.mint(beneficiary,ether(amount),{from:owner}), msg);
        } else {
            let receipt = await ERC20Instance.mint(beneficiary,ether(amount),{from:owner});
            expectEvent(receipt,'Transfer',{
                from: constants.ZERO_ADDRESS,
                to: beneficiary,
                value: ether(amount),
            });
        }
    });
}

//添加暂停管理员
exports.addMinter = (minter,sender,desc,reject, msg) => {
    it(desc + ':addMinter()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.addMinter(minter,{from:sender}), msg);
        } else {
            let receipt = await ERC20Instance.addMinter(minter,{from:sender});
            expectEvent(receipt, 'MinterAdded',{
                account: minter
            });
        }
    });
}

//给账户添加暂停权
exports.isMinter = (minter,isMinter,desc) => {
    it(desc + ': isMinter()', async function () {
        assert.equal(isMinter,await ERC20Instance.isMinter(minter));
    });
}

//撤销暂停管理员
exports.renounceMinter = (minter,desc,reject,msg) => {
    it(desc + ':renounceMinter()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.renounceMinter({from: minter}), msg);
        } else {
            let receipt = await ERC20Instance.renounceMinter({from: minter});
            expectEvent(receipt, 'MinterRemoved', {
                account: minter
            });
        }
    });
}

//给普通用户，添加暂停权限
exports.addPauser = (pauser, sender, desc, reject, msg) => {
    it(desc + ':addPauser()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.addPauser(pauser,{from: sender}), msg);
        } else {
            let receipt = await ERC20Instance.addPauser(pauser, {from: sender});
            expectEvent(receipt,'PauserAdded', {
                account: pauser
            });
        }
    });
}

//判断用户是否有暂停权
exports.isPauser = (pauser,isPauser,desc) => {
    it(desc +':isPauser()', async function(){
        assert.equal(isPauser, await ERC20Instance.isPauser(pauser));
    });
}

//测序普通用户的暂停权限
exports.renouncePauser = (pauser,desc,reject,msg) => {
    it(desc + ': renouncePauser()', async function () {
        if(reject){
            await assert.rejects(ERC20Instance.renouncePauser({from: pauser}), msg);
        } else {
            let receipt = await ERC20Instance.renouncePauser({from: pauser});
            expectEvent(receipt,'PauserRemoved',{
                account: pauser
            });
        }
    });
}

//测试暂停状态
exports.paused = (paused, desc) => {
    it(desc + ':paused()', async function(){
        assert.equal(paused, await ERC20Instance.paused());
    });
}

//测试用户的暂停权限
exports.pause = (pauser,desc,reject, msg) => {
    it(desc + ': pause()', async function () {
        if(reject){
            await assert.rejects(ERC20Instance.pause({from:pauser}), msg);
        } else {
            let receipt = await ERC20Instance.pause({from:pauser});
            expectEvent(receipt,'Paused',{
                account: pauser
            });
        }
    });
}

//测试恢复合约
exports.unpause = (pauser,desc, reject, msg) => {
    it(desc + ':unpause()',async function(){
        if(reject){
            await assert.rejects(ERC20Instance.unpause({from:pauser}),msg);
        } else {
            let receipt = await ERC20Instance.unpause({from: pauser});
            expectEvent(receipt, 'Unpaused', {
                account: pauser
            });
        }
    });
}